package model.wrap.type;

import java.util.ArrayList;
import java.util.List;

import model.forview.TypeCreateModelForView;
import model.wrap.node.Node;

public class Type
{
    protected models.Type type;

    public static ArrayList<Type> getAllTypes()
    {
	ArrayList<Type> allTypes = new ArrayList<Type>();

	List<models.Type> allModelsTypes = models.Type.find.where().findList();
	for (models.Type type : allModelsTypes)
	{
	    allTypes.add(new Type(type));
	}

	return allTypes;
    }

    public void save()
    {
	type.save();
    }

    public Type(Long id)
    {
	this.type = models.Type.getInstanceById(id);
    }

    public Type(models.Type type)
    {
	this.type = type;
    }

    public Type(TypeCreateModelForView form)
    {
	type = new models.Type();
	setTitle(form.title);
	setDescription(form.description);
	setTypeTitle(form.type_title);
	setTypeName(form.type_name);
    }

    /**Получить массив с сокращенными именами примитивных типов, которые находятся в данном типе.
     * @author pocteg
     * @return Return values like [p, s, s ,b , p, f, f]
     */
    public ArrayList<String> getSimpleTypesName()
    {
	ArrayList<String> simpTp = new ArrayList<String>();
	
	String[] st = this.type.getType_name().split(Node.SEPARATOR_FOR_CONTENT);
	
	for (String string : st)
	{
	    simpTp.add(string);
	}
	
	return simpTp;
    }
    
    /**Получить массив с сокращенными именами примитивных типов, которые находятся в данном типе.
     * @author pocteg
     * @return Return values like [Ссылка, Файл, Строка , Файл]
     */
    public ArrayList<String> getSimpleTypesNameTitle()
    {
	ArrayList<String> simpTp = new ArrayList<String>();
	
	String[] st = this.type.getType_name().split(Node.SEPARATOR_FOR_CONTENT);
	
	for (String string : st)
	{
	    String result = "";
	    if(string.equals(Type.BYTE))
		result = Type.BYTE_TITLE;
	    if(string.equals(Type.STRING))
		result = Type.STRING_TITLE;
	    if(string.equals(Type.FLOAT))
		result = Type.FLOAT_TITLE;
	    if(string.equals(Type.POINT))
		result = Type.POINT_TITLE;
	    if(string.equals(Type.USER))
		result = Type.USER_TITLE;
	    simpTp.add(result);
	}
	
	return simpTp;
    }
    
    /**
     * Получить массив с заголовками для всех аттрибутов типа.
     * @return Return values like [Last name, first name, age]
     */
    public ArrayList<String> getSimpleTypesTitle()
    {
	ArrayList<String> titleArray = new ArrayList<String>();
	
	String[] titleSt = this.type.getType_title().split(Node.SEPARATOR_FOR_CONTENT);
	
	for (String string : titleSt)
	{
	    titleArray.add(string);
	}
	
	return titleArray;
    }
    
    public long getID()
    {
	return this.type.getId();
    }

    public long getId()
    {
	return this.type.getId();
    }
    
    public String getTitle()
    {
	return type.getTitle();
    }

    public void setTitle(String title)
    {
	type.setTitle(title);
    }

    public String getDescription()
    {
	return type.getDescription();
    }

    public void setDescription(String description)
    {
	type.setDescription(description);
    }

    public static String createDefaultValuesForNode(Node node)
    {
	ArrayList<String> allTypes = node.getType().getArrayTypes();
	String allElement = "";

	for (String lType : allTypes)
	{
	    if (lType.equals(Type.BYTE))
	    {
		ByteElement elem = ByteElement.createDefaultValueForNode(node);
		allElement += elem.getId().toString() + Type.SEPARATOR_CHARACTER;
	    }
	    if (lType.equals(Type.FLOAT))
	    {
		FloatElement elem = FloatElement.createDefaultValueForNode(node);
		allElement += elem.getId().toString() + Type.SEPARATOR_CHARACTER;
	    }
	    if (lType.equals(Type.POINT))
	    {
		PointElement elem = PointElement.createDefaultValueForNode(node);
		allElement += elem.getId().toString() + Type.SEPARATOR_CHARACTER;
	    }
	    if (lType.equals(Type.STRING))
	    {
		StringElement elem = StringElement.createDefaultValueForNode(node);
		allElement += elem.getId().toString() + Type.SEPARATOR_CHARACTER;
	    }
	    if (lType.equals(Type.USER))
	    {
		UserElement elem = UserElement.createDefaultValueForNode(node);
		allElement += elem.getId().toString() + Type.SEPARATOR_CHARACTER;
	    }
	}
	
	return allElement;
    }

    public ArrayList<String> getArrayTypes()
    {
	ArrayList<String> allTypes = new ArrayList<String>();
	String[] tp = this.getTypeName().split(";");
	for (int i = 0; i < tp.length; i++)
	{
	    allTypes.add(tp[i]);
	}
	return allTypes;
    }

    public String getTypeName()
    {
	return type.getType_name();
    }

    public void setTypeName(String typeName)
    {
	type.setType_name(typeName);
    }

    public String getTypeTitle()
    {
	return type.getType_title();
    }

    public void setTypeTitle(String typeTitle)
    {
	type.setType_title(typeTitle);
    }
    
    public void delete() throws Exception
    {
	ArrayList<Node> nodes = Node.getNodesByType(this);
	if(nodes.size() == 0)
	    this.type.delete();
	else
	    throw new Exception("Элемент используется.");
    }

    public final static String BYTE = "b";
    public final static String POINT = "p";
    public final static String STRING = "s";
    public final static String FLOAT = "f";
    public final static String USER = "u";
    
    public final static String BYTE_TITLE = "Файл";
    public final static String POINT_TITLE = "Ссылка на узел";
    public final static String STRING_TITLE = "Строка";
    public final static String FLOAT_TITLE = "Число";
    public final static String USER_TITLE = "Пользователь";

    public final static String SEPARATOR_CHARACTER = ";";

}
